package DB;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class DirDB implements DirDBMan
{
	private SessionFactory seFac;

	public DirDB()
	{
	}

	public DirDB(SessionFactory sessionFactory)
	{
		seFac = sessionFactory;
	}
	

	/**
	 * add new Directory to the table
	 * @param path string that contain the path of the directory
	 * @return an object of the new directory or null if it doesn't exist
	 */
	public Directories addDir(String path) 
	{
		Session se = seFac.openSession();
		Directories  dir = null;
		String sqlQuery="from Directories where dirName=:path"; 
		//the query to get the directory
		Query query = se.createQuery(sqlQuery).setParameter("path", path.toString());
		if(!query.list().isEmpty())
		{
			List <Directories>list = query.list();
			Iterator<Directories> it=list.iterator();
			//get the requested dir
			dir = it.next();
		}
		if(dir == null)
		{
			dir = new Directories();
			dir.setDirName(path);
			se.save(dir);
			se.flush();
			se.close();
			return dir;
		}
		else 
			return null; /* dir already exist */
	}

	/**
	 * add new expression to the table
	 * @param exp string that contain the regular expression
	 * @return an object of the new expression or null if it doesn't exist
	 */
	public RegExpres addExp(String exp) 
	{
		Session se = seFac.openSession();
		RegExpres  rExp = null;
		Query query = se.createQuery("from RegExpres where expName='"+exp+"'");
		if(!query.list().isEmpty())
		{
			List <RegExpres>list = query.list();
			Iterator<RegExpres> it=list.iterator();
			rExp = it.next();
		}
		if(rExp == null)
		{
			rExp = new RegExpres();
			rExp.setExpName(exp);
			se.save(rExp);
			se.flush();
			se.close();
			return rExp;
		}
		else
		{
			se.close();
			return null; /* expression already exist */
		}
	}

	/**
	 * add new expression to the table
	 * @param exp string that contain the regular expression
	 * @param path string that contain the path of the directory
	 * @return true if succeed to add the expression to the requested directory, or false if not. 
	 */
	public boolean addRegExToDir(String exp, String path) 
	{
		Session se = seFac.openSession();
		RegExpres  rExp = null;
		Query query = se.createQuery("from RegExpres where expName='"+exp+"'");
		if(!query.list().isEmpty())
		{
			List <RegExpres>list = query.list();
			Iterator<RegExpres> it=list.iterator();
			rExp = it.next();
		}
		if(rExp == null)
		{
			rExp = addExp(exp);
		}
		
		Directories  dir = null;
		String sqlQuery="from Directories where dirName=:path"; 
		//the query to get the directory
		query = se.createQuery(sqlQuery).setParameter("path", path.toString());
		if(!query.list().isEmpty())
		{
			List <Directories>list = query.list();
			Iterator<Directories> it=list.iterator();
			//get the requested dir
			dir = it.next();
		}
		if(dir != null)
		{
			dir.getExp().add(rExp);       
			se.flush();
			se.close();
			return true;
		}
		se.close();
		return false;
	}
	
	/**
	 * delete all the directories on the table
	 */
	public void delAllDirs() 
	{
		Session se = seFac.openSession();
		Query query = se.createQuery("delete from Directories");
		query.executeUpdate();
		se.flush();
		se.clear();
		se.close();
	}
	
	/**
	 * delete all the expressions on the table
	 */
	public void delAllRegExp() 
	{
		Session se = seFac.openSession();
		Query query = se.createQuery("from RegExpres");
		if(!query.list().isEmpty())
		{
			List <RegExpres>list = query.list();
			Iterator<RegExpres> it=list.iterator();
			while(it.hasNext())
			{
				se.delete( it.next());
				se.flush();
			}
		}
		se.close();
	}

	/**
	 * delete expression from requested directory
	 * @param exp string that contain the regular expression
	 * @param path string that contain the path of the directory
	 * @return true if succeed to delete the expression from the requested directory, or false if not. 
	 */
	public boolean delRegExpFromDir(String exp, String path) 
	{
		Session se = seFac.openSession();
		RegExpres  rExp = null;
		Query query = se.createQuery("from RegExpres where expName='"+exp+"'");
		if(!query.list().isEmpty())
		{
			List <RegExpres>list = query.list();
			Iterator<RegExpres> it=list.iterator();
			rExp = it.next();
		}
		if(rExp == null)
		{
			se.close();
			return true;
		}

		Directories  dir = null;
		String sqlQuery="from Directories where dirName=:path"; 
		//the query to get the directory
		query = se.createQuery(sqlQuery).setParameter("path", path.toString());
		if(!query.list().isEmpty())
		{
			List <Directories>list = query.list();
			Iterator<Directories> it=list.iterator();
			//get the requested dir
			dir = it.next();
		}
		if(dir != null)
		{
			dir.getExp().remove(rExp); 
		}
		se.close();
		return false; //no such file
	}
	
	/**
	 * delete directory from the table
	 * @param path string that contain the path of the directory
	 * @return true if succeed to delete the directory, or false if not. 
	 */
	public boolean deleteDir(String path) 
	{
		Session se = seFac.openSession();
		path = path.replace("\\", "\\\\\\\\");
		//Directories dir = getDirByPath(path);
		path = path+"%";
		//the query to get the directory
		Query query = se.createQuery("from Directories where dirName like '"+path+"'");
		Directories dir = null;
		if(!query.list().isEmpty())
		{
			List <Directories>list = query.list();
			Iterator<Directories> it=list.iterator();
			while(it.hasNext())
			{
				se.delete(it.next());
				se.flush();
			}
			se.close();
			return true;
		}
		return false;
	}
	
	/**
	 * delete expression from the table
	 * @param exp string that contain the expression
	 * @return true if succeed to delete the expression, or false if not. 
	 */
	public boolean deleteRegExp(String exp) 
	{
		Session se = seFac.openSession();
		RegExpres  rExp = null;
		Query query = se.createQuery("from RegExpres where expName='"+exp+"'");
		if(!query.list().isEmpty())
		{
			List <RegExpres>list = query.list();
			Iterator<RegExpres> it=list.iterator();
			rExp = it.next();
		}
		if(rExp != null)
		{
			se.delete(rExp);
			se.flush();
			se.close();
			return true;
		}
		else
		{
			se.close();
			return false;
		}
	}
	
	/**
	 * this function return all the directories that in the table
	 * @return array list that contain all the paths of the dirs
	 */
	public ArrayList<String> getAllDirs() 
	{
		Session se = seFac.openSession();
		ArrayList<String> dirs = null;
		Query query = se.createQuery("from Directories");
		if(!query.list().isEmpty())
		{
			dirs  = new ArrayList<String>();
			List <Directories> list = query.list();
			Iterator<Directories> it=list.iterator();
			while(it.hasNext())
				dirs.add( it.next().getDirName());
		}
		se.close();
		return dirs;
	}
	
	/**
	 * this function return all the expressions that in the table
	 * @return array list that contain all the names of the expressions
	 */
	public ArrayList<String> getAllExps() 
	{
		Session se = seFac.openSession();
		ArrayList<String> exps = null;
		Query query = se.createQuery("from RegExpres");
		if(!query.list().isEmpty())
		{
			exps =  new ArrayList<String>();
			List <RegExpres> list = query.list();
			Iterator<RegExpres> it=list.iterator();
			while(it.hasNext())
				exps.add( it.next().getExpName());
		}
		return exps;
	}
	
	/**
	 * this function return all the dirs that the user chose for them the requested expression
	 * @param exp string with the expression
	 * @return array list that contain all the paths of the dirs
	 */
	public ArrayList<String> getDirs(String exp) 
	{
		Session se = seFac.openSession();
		RegExpres  rExp = null;
		Query query = se.createQuery("from RegExpres where expName='"+exp+"'");
		if(!query.list().isEmpty())
		{
			List <RegExpres>list = query.list();
			Iterator<RegExpres> it=list.iterator();
			rExp = it.next();
		}
		ArrayList<String> dirs = null;
		if(rExp != null)
		{
			dirs = new ArrayList<String>();
			Set<Directories> d = rExp.getDirs();
			Iterator<Directories> it = d.iterator();
			while(it.hasNext())
				dirs.add( it.next().getDirName());
		}
		se.close();
		return dirs;
	}
	
	/**
	 * this function return all the expressions that the user chose for them the requested dir
	 * @param path string with the path of the directories
	 * @return array list that contain all the names of the expressions
	 */
	public ArrayList<String> getExps(String path) 
	{
		Session se = seFac.openSession();
		Directories  dir = null;
		String sqlQuery="from Directories where dirName=:path"; 
		//the query to get the directory
		Query query = se.createQuery(sqlQuery).setParameter("path", path.toString());
		if(!query.list().isEmpty())
		{
			List <Directories>list = query.list();
			Iterator<Directories> it=list.iterator();
			//get the requested dir
			dir = it.next();
		}
		ArrayList<String> exps = null;
		if(dir != null)
		{
			exps = new ArrayList<String>();
			Set<RegExpres> rx = dir.getExp();
			Iterator<RegExpres> it = rx.iterator();
			while(it.hasNext())
				exps.add( it.next().getExpName());
		}
		return exps;
	}
	
}
